//=============================================================================
/**
 *
 *	@file		encount_effect_legend.c
 *	@brief		エンカウントエフェクト：伝説
 *	@author		hosaka genya
 *	@data		2009.02.24
 *	@note		encount_effect_subから抜粋
 *
 */
//=============================================================================
#include "common.h"
#include "system/lib_pack.h"
#include "system/brightness.h"
#include "fieldsys.h"
#include "fieldmap_work.h"
#include "field_event.h"
#include "fld_motion_bl.h"
#include "encount_effect_def.h"
#include "system/wipe.h"
#include "system/laster.h"
#include "system/fontproc.h"
#include "field_encounteffect.naix"
#include "savedata/mystatus.h"
#include "include/battle/trtype_def.h"
#include "include/battle/trno_def.h"
#include "include/msgdata/msg.naix"

#include "field/fieldmap.h"

#include "encount_effect_legend.h"


//-----------------------------------------------------------------------------
/**
 *					コーディング規約
 *		●関数名
 *				１文字目は大文字それ以降は小文字にする
 *		●変数名
 *				・変数共通
 *						constには c_ を付ける
 *						staticには s_ を付ける
 *						ポインタには p_ を付ける
 *						全て合わさると csp_ となる
 *				・グローバル変数
 *						１文字目は大文字
 *				・関数内変数
 *						小文字と”＿”と数字を使用する 関数の引数もこれと同じ
*/
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
/**
 *
 *		伝説ポケモン　エンカウント [ LEGEND ]
 *
 */
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/**
 *					定数宣言
*/
//-----------------------------------------------------------------------------
//-------------------------------------
//	伝説ポケモン
//=====================================
// シーケンス
enum{
	ENCOUNT_LEGEND_NORMAL_START,
	ENCOUNT_LEGEND_NORMAL_FLASH_INI,
	ENCOUNT_LEGEND_NORMAL_FLASH_WAIT,
	ENCOUNT_LEGEND_NORMAL_MOTIONBL_S,
	ENCOUNT_LEGEND_NORMAL_CAMERA_SET,
	ENCOUNT_LEGEND_NORMAL_FADE,
	ENCOUNT_LEGEND_NORMAL_FADEWAIT,
	ENCOUNT_LEGEND_NORMAL_END,
};

// カメラテーブル
typedef struct{
	u32 dist;		// 距離
	u16 angle_x;	// Angle
	u16 angle_y;
	u16 purse;		// パース
	u16 wait;
} ENCOUNT_LEGEND_CAMERA_TBL;


// カメラテーブル	(触ってよい)
#define ENCOUNT_LEGEND_CAMERA_TBL_NUM	( 16 )	// ここを増やし、下のテーブルの数を合わせると、テーブルの数も変更できます。
static const ENCOUNT_LEGEND_CAMERA_TBL EncLegendNormalCamera[ ENCOUNT_LEGEND_CAMERA_TBL_NUM ] = {
	{	// 0
		0x29AEC1,		// 距離
		0xD602,			// AngleX
		0x0,			// AngleY
		0x5C1,			// パース
		4,				// ウエイト
	},
	{	// 1
		0x29AEC1,		// 距離
		0xcf02,			// AngleX
		0xff00,			// AngleY
		0x601,			// パース
		4,				// ウエイト
	},
	{	// 2
		0x29AEC1,		// 距離
		0xe602,			// AngleX
		0x1000,			// AngleY
		0x691,			// パース
		4,				// ウエイト
	},
	{	// 3
		0x29AEC1,		// 距離
		0xD602,			// AngleX
		0xa00,			// AngleY
		0x711,			// パース
		3,				// ウエイト
	},
	{	// 4
		0x29AEC1,		// 距離
		0xe102,			// AngleX
		0xf000,			// AngleY
		0x780,			// パース
		3,				// ウエイト
	},
	{	// 5
		0x29AEC1,		// 距離
		0xc602,			// AngleX
		0x0000,			// AngleY
		0x751,			// パース
		3,				// ウエイト
	},
	{	// 6
		0x29AEC1,		// 距離
		0xe002,			// AngleX
		0xf000,			// AngleY
		0x800,			// パース
		3,				// ウエイト
	},
	{	// 7
		0x29AEC1,		// 距離
		0xD602,			// AngleX
		0,				// AngleY
		0x802,			// パース
		3,				// ウエイト
	},
	{	// 8
		0x29AEC1,		// 距離
		0xD002,			// AngleX
		0x1000,			// AngleY
		0x800,			// パース
		3,				// ウエイト
	},
	{	// 9
		0x29AEC1,		// 距離
		0xD902,			// AngleX
		0xf500,			// AngleY
		0x751,			// パース
		3,				// ウエイト
	},
	{	// 10
		0x29AEC1,		// 距離
		0xD002,			// AngleX
		0xa00,			// AngleY
		0x4C1,			// パース
		2,				// ウエイト
	},
	{	// 11
		0x29AEC1,		// 距離
		0xe002,			// AngleX
		0xf000,			// AngleY
		0x3C1,			// パース
		2,				// ウエイト
	},
	{	// 12
		0x29AEC1,		// 距離
		0xD002,			// AngleX
		0xf000,			// AngleY
		0x650,			// パース
		1,				// ウエイト
	},
	{	// 13
		0x29AEC1,		// 距離
		0xe002,			// AngleX
		0xa000,			// AngleY
		0x241,			// パース
		1,				// ウエイト
	},
	{	// 14
		0x29AEC1,		// 距離
		0xe1a2,			// AngleX
		0x500,			// AngleY
		0x500,			// パース
		1,				// ウエイト
	},
	{	// 15
		0x29AEC1,		// 距離
		0xD602,			// AngleX
		0,				// AngleY
		0x241,			// パース
		1,				// ウエイト
	},
};

// 動さパラメータ	（触ってよい部分）
#define ENCOUNT_LEGEND_NORMAL_FADE_SYNC		( 10 )	// フェードシンク
#define ENCOUNT_LEGEND_NORMAL_MOTIONBL_EVA	( 3 )	// モーションブラー係数　新しくブレンドされる絵
#define ENCOUNT_LEGEND_NORMAL_MOTIONBL_EAB	( 15 )	// モーションブラー係数　すでにバッファされている絵


//-------------------------------------
//	パッケージポケモン
//=====================================
// シーケンス
enum{
	ENCOUNT_LEGEND_PACKAGE_START,
	ENCOUNT_LEGEND_PACKAGE_FLASH_INI,
	ENCOUNT_LEGEND_PACKAGE_FLASH_WAIT,
	ENCOUNT_LEGEND_PACKAGE_MOTIONBL_S,
	ENCOUNT_LEGEND_PACKAGE_PURSE,
	ENCOUNT_LEGEND_PACKAGE_CAMERA,
	ENCOUNT_LEGEND_PACKAGE_CAMERAWAIT,
	ENCOUNT_LEGEND_PACKAGE_FADE,
	ENCOUNT_LEGEND_PACKAGE_FADEWAIT,
	ENCOUNT_LEGEND_PACKAGE_END,
};

//--------------------------------------------------------------
///	パッケージポケモン 動作パラメータ
//==============================================================
typedef struct {
	u8 PurseSync;		// パースシンク
	u8 CameraMoveWait;	// カメラ待ちシンク
	u8 CameraSync;		// カメラシンク
	u8 FadeSync;		// フェードシンク
	int PurseMove;		// パース変動値
	fx32 CameraMove;	// カメラ動作値
	fx32 CameraSS;
	u16 Motionbl_EVA;	// モーションブラー係数 新しくブレンドされる絵
	u16 Motionbl_EAB;	// モーションブラー係数 すでにバッファされている絵
} ENCOUNT_LEGEND_PARAM;

// ホウオウ
static const ENCOUNT_LEGEND_PARAM ENCOUNT_LEGEND_HououDef = {
	40, 5, 8, 60, 0x100,
	-FX32_CONST(660),	// 200
	FX32_CONST(0.5),	// 0.0f
	5, 13,
};

// ルギア
static const ENCOUNT_LEGEND_PARAM ENCOUNT_LEGEND_RugiaDef = {
	40, 5, 8, 60, 0x100,
	-FX32_CONST(550),	// 200
	FX32_CONST(0.5),	// 0.0f
	5, 13,
};


//-----------------------------------------------------------------------------
/**
 *					構造体宣言
*/
//-----------------------------------------------------------------------------
//-------------------------------------
//	伝説ポケモン
//=====================================
typedef struct {
	FLD_MOTION_BL_DATA_PTR	motion;
	GF_CAMERA_PTR	camera;		// カメラデータ
	u32 camera_count;
	s32 wait;
} ENCOUNT_LEGEND_NORMAL;

//-------------------------------------
//	PACKAGEポケモン
//=====================================
typedef struct {
	FLD_MOTION_BL_DATA_PTR	motion;
	GF_CAMERA_PTR	camera;		// カメラデータ
	ENC_MOVE_WORK purse;
	ENC_ADDMOVE_WORK_FX camra_zoom;
	s32 wait;
} ENCOUNT_LEGEND_PACKAGE;



// カメラデータ設定
static void ENC_LegendCameraSet( FIELDSYS_WORK* fsys, const ENCOUNT_LEGEND_CAMERA_TBL* cp_data )
{
	CAMERA_ANGLE angle;

	// カメラパラメータ設定
	GFC_SetCameraPerspWay( cp_data->purse, fsys->camera_ptr );
	GFC_SetCameraDistance( cp_data->dist, fsys->camera_ptr );
	angle.x = cp_data->angle_x;
	angle.y = cp_data->angle_y;
	angle.z = 0;
	GFC_SetCameraAngleRev( &angle, fsys->camera_ptr );
}


//----------------------------------------------------------------------------
/**
 *	@brief	伝説ポケモン　エンカウント
 */
//-----------------------------------------------------------------------------
void EncountEffect_Legend_Normal(TCB_PTR tcb, void* work)
{
	ENCOUNT_EFFECT_WORK *eew = work;
	ENCOUNT_LEGEND_NORMAL* task_w = eew->work;

	switch(eew->seq){
	case ENCOUNT_LEGEND_NORMAL_START:	// 初期化処理
		eew->work = sys_AllocMemory(HEAPID_FIELD, sizeof(ENCOUNT_LEGEND_NORMAL));
		memset( eew->work, 0, sizeof(ENCOUNT_LEGEND_NORMAL) );

		GF_Disp_GX_VisibleControl(GX_PLANEMASK_BG1, VISIBLE_OFF);
		GF_Disp_GX_VisibleControl(GX_PLANEMASK_BG2, VISIBLE_OFF);
		GF_Disp_GX_VisibleControl(GX_PLANEMASK_BG3, VISIBLE_OFF);

		eew->seq++;
		break;

	case ENCOUNT_LEGEND_NORMAL_FLASH_INI:
		EncountFlashTask(MASK_MAIN_DISPLAY, 16, 16,  &eew->wait, 1);

		eew->seq++;
		break;

	case ENCOUNT_LEGEND_NORMAL_FLASH_WAIT:
		if(eew->wait){
			eew->seq++;
		}
		break;

	case ENCOUNT_LEGEND_NORMAL_MOTIONBL_S:	// モーションブラーを使用する準備
		task_w->motion = FLDMotionBl_Init(ENCOUNT_LEGEND_NORMAL_MOTIONBL_EVA, ENCOUNT_LEGEND_NORMAL_MOTIONBL_EAB);
		task_w->camera_count = 0;
		task_w->wait = EncLegendNormalCamera[ task_w->camera_count ].wait;
		eew->seq++;
		break;

	case ENCOUNT_LEGEND_NORMAL_CAMERA_SET:
		task_w->wait --;
		if( task_w->wait < 0 ){

			// カメラ設定
			ENC_LegendCameraSet( eew->fsw, &EncLegendNormalCamera[ task_w->camera_count ] );

			task_w->camera_count++;
			if( task_w->camera_count >= ENCOUNT_LEGEND_CAMERA_TBL_NUM ){
				eew->seq++;
			}else{
				task_w->wait = EncLegendNormalCamera[ task_w->camera_count ].wait;
			}
		}
		break;

	case ENCOUNT_LEGEND_NORMAL_FADE:
		WIPE_SYS_Start( WIPE_PATTERN_M, WIPE_TYPE_FADEOUT, WIPE_TYPE_FADEOUT, WIPE_FADE_WHITE, ENCOUNT_LEGEND_NORMAL_FADE_SYNC, 1, HEAPID_FIELD );
		eew->seq++;
		break;

	case ENCOUNT_LEGEND_NORMAL_FADEWAIT:
		if( WIPE_SYS_EndCheck() ){
			eew->wait = 0;

			eew->seq++;
		}
		break;


	case ENCOUNT_LEGEND_NORMAL_END:		// 後始末
		WIPE_SetBrightness( WIPE_DISP_SUB, WIPE_FADE_WHITE );

		// 元に戻す
		FLDMotionBl_Delete(&task_w->motion);

		// ブライトネス解除
		G2_BlendNone();

		if(eew->end != NULL){
			*(eew->end) = TRUE;		// タスク終了を報告
		}
		ENC_End( eew, tcb );
		WIPE_SetBrightness( WIPE_DISP_SUB, WIPE_FADE_WHITE );
		break;
	}
}


//----------------------------------------------------------------------------
/**
 *	@brief	ﾊﾟｯｹｰｼﾞポケモン　エンカウント
 */
//-----------------------------------------------------------------------------
static void EncountEffect_Legend_Core(TCB_PTR tcb, void* work, const ENCOUNT_LEGEND_PARAM* cp_def )
{
	ENCOUNT_EFFECT_WORK *eew = work;
	ENCOUNT_LEGEND_PACKAGE* task_w = eew->work;
	BOOL result;

	switch(eew->seq){
	case ENCOUNT_LEGEND_PACKAGE_START:	// 初期化処理
		eew->work = sys_AllocMemory(HEAPID_FIELD, sizeof(ENCOUNT_LEGEND_PACKAGE));
		memset( eew->work, 0, sizeof(ENCOUNT_LEGEND_PACKAGE) );

		GF_Disp_GX_VisibleControl(GX_PLANEMASK_BG1, VISIBLE_OFF);
		GF_Disp_GX_VisibleControl(GX_PLANEMASK_BG2, VISIBLE_OFF);
		GF_Disp_GX_VisibleControl(GX_PLANEMASK_BG3, VISIBLE_OFF);

		eew->seq++;
		break;

	case ENCOUNT_LEGEND_PACKAGE_FLASH_INI:
		EncountFlashTask(MASK_MAIN_DISPLAY, 16, 16,  &eew->wait, 1);

		eew->seq++;
		break;

	case ENCOUNT_LEGEND_PACKAGE_FLASH_WAIT:
		if(eew->wait){
			eew->seq++;
		}
		break;

	case ENCOUNT_LEGEND_PACKAGE_MOTIONBL_S:	// モーションブラーを使用する準備
		task_w->motion = FLDMotionBl_Init(cp_def->Motionbl_EVA, cp_def->Motionbl_EAB);

		// パース設定
		{
			u16 pers = GFC_GetCameraPerspWay( eew->fsw->camera_ptr );
			ENC_MoveReq( &task_w->purse, pers, pers + cp_def->PurseMove, cp_def->PurseSync );
		}

		eew->seq++;
		break;

	case ENCOUNT_LEGEND_PACKAGE_PURSE:
		result = ENC_MoveMain( &task_w->purse );
		GFC_SetCameraPerspWay( task_w->purse.x, eew->fsw->camera_ptr );
		if( result == TRUE ){
			eew->seq++;
			task_w->wait = cp_def->CameraMoveWait;
		}
		break;

	case ENCOUNT_LEGEND_PACKAGE_CAMERA:
		task_w->wait --;
		if( task_w->wait < 0 ){
			fx32 dist = GFC_GetCameraDistance( eew->fsw->camera_ptr );
			ENC_AddMoveReqFx( &task_w->camra_zoom,
					dist,
					dist + cp_def->CameraMove,
					cp_def->CameraSS,
					cp_def->CameraSync );

			eew->seq ++;
		}
		break;

	case ENCOUNT_LEGEND_PACKAGE_CAMERAWAIT:
		result = ENC_AddMoveMainFx( &task_w->camra_zoom );
		GFC_SetCameraDistance( task_w->camra_zoom.x, eew->fsw->camera_ptr );
		if( result == TRUE ){
			eew->seq++;
		}
		break;

	case ENCOUNT_LEGEND_PACKAGE_FADE:
		WIPE_SYS_Start( WIPE_PATTERN_M, WIPE_TYPE_FADEOUT, WIPE_TYPE_FADEOUT, WIPE_FADE_WHITE, cp_def->FadeSync, 1, HEAPID_FIELD );
		eew->seq++;
		break;

	case ENCOUNT_LEGEND_PACKAGE_FADEWAIT:
		if( WIPE_SYS_EndCheck() ){
			eew->wait = 0;
			eew->seq++;
		}
		break;


	case ENCOUNT_LEGEND_PACKAGE_END:		// 後始末
		WIPE_SetBrightness( WIPE_DISP_SUB, WIPE_FADE_WHITE );

		// 元に戻す
		FLDMotionBl_Delete(&task_w->motion);

		// ブライトネス解除
		G2_BlendNone();

		if(eew->end != NULL){
			*(eew->end) = TRUE;		// タスク終了を報告
		}
		ENC_End( eew, tcb );
		WIPE_SetBrightness( WIPE_DISP_SUB, WIPE_FADE_WHITE );
		break;
	}
}

void EncountEffect_Legend_Houou( TCB_PTR tcb, void* work )
{
	EncountEffect_Legend_Core( tcb, work, &ENCOUNT_LEGEND_HououDef );
}

void EncountEffect_Legend_Rugia( TCB_PTR tcb, void* work )
{
	EncountEffect_Legend_Core( tcb, work, &ENCOUNT_LEGEND_RugiaDef );
}
